using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

class Teacher
{
    public Student stu;
    
    ~Teacher()
    {
        Debug.Log("Teacher销毁");
    }
}
class Student
{
    public string name;
    public int age;
    
    ~Student()
    {
        Debug.Log("Student销毁");
    }
}
public class TestC1 : MonoBehaviour
{
    void Start()
    {
        //GC.GetTotalMemory(false) 返回托管堆当前分配的字节数。
        Debug.Log("Memory："+GC.GetTotalMemory(false));
        var t = new Teacher();
        var s1 = new Student(){name = "GC类包含了可使用户与垃圾回收机制进行互操作的静态方法，包括发起新一轮垃圾回收操作的方法。确定某对象当前所在代的方法及当前分配内存空间的方法。\n\nGC.Collect();//无参时将发起一轮全面的回收。（ 完全回收之前，应用程序会停止响应，因此不建议使用。）\nGC.Collect(i);//(0<=i<=2)对第i代进行垃圾回收。\nGetTotalMemory将返因分配于托管堆上的内存空间总量。当参数为True时，在计算之前将进行一轮全面的垃圾回收。如下所示：\n\nlong totalMemory = System.GC.GetTotalMemory(True);\n下面是 在.NET Framework 2.0 版中是新增的公共方法：\n\n通知运行库在安排垃圾回收时应考虑分配大量的非托管内存\npublic static void AddMemoryPressure (\nlong bytesAllocated)//bytesAllocated已分配的非托管内存的增量。", age = 30};
        var s2 = new Student(){name = "GC类包含了可使用户与垃圾回收机制进行互操作的静态方法，包括发起新一轮垃圾回收操作的方法。确定某对象当前所在代的方法及当前分配内存空间的方法。\n\nGC.Collect();//无参时将发起一轮全面的回收。（ 完全回收之前，应用程序会停止响应，因此不建议使用。）\nGC.Collect(i);//(0<=i<=2)对第i代进行垃圾回收。\nGetTotalMemory将返因分配于托管堆上的内存空间总量。当参数为True时，在计算之前将进行一轮全面的垃圾回收。如下所示：\n\nlong totalMemory = System.GC.GetTotalMemory(True);\n下面是 在.NET Framework 2.0 版中是新增的公共方法：\n\n通知运行库在安排垃圾回收时应考虑分配大量的非托管内存\npublic static void AddMemoryPressure (\nlong bytesAllocated)//bytesAllocated已分配的非托管内存的增量。", age = 30};
        var s3 = new Student(){name = "GC类包含了可使用户与垃圾回收机制进行互操作的静态方法，包括发起新一轮垃圾回收操作的方法。确定某对象当前所在代的方法及当前分配内存空间的方法。\n\nGC.Collect();//无参时将发起一轮全面的回收。（ 完全回收之前，应用程序会停止响应，因此不建议使用。）\nGC.Collect(i);//(0<=i<=2)对第i代进行垃圾回收。\nGetTotalMemory将返因分配于托管堆上的内存空间总量。当参数为True时，在计算之前将进行一轮全面的垃圾回收。如下所示：\n\nlong totalMemory = System.GC.GetTotalMemory(True);\n下面是 在.NET Framework 2.0 版中是新增的公共方法：\n\n通知运行库在安排垃圾回收时应考虑分配大量的非托管内存\npublic static void AddMemoryPressure (\nlong bytesAllocated)//bytesAllocated已分配的非托管内存的增量。", age = 30};
        var s4 = new Student(){name = "GC类包含了可使用户与垃圾回收机制进行互操作的静态方法，包括发起新一轮垃圾回收操作的方法。确定某对象当前所在代的方法及当前分配内存空间的方法。\n\nGC.Collect();//无参时将发起一轮全面的回收。（ 完全回收之前，应用程序会停止响应，因此不建议使用。）\nGC.Collect(i);//(0<=i<=2)对第i代进行垃圾回收。\nGetTotalMemory将返因分配于托管堆上的内存空间总量。当参数为True时，在计算之前将进行一轮全面的垃圾回收。如下所示：\n\nlong totalMemory = System.GC.GetTotalMemory(True);\n下面是 在.NET Framework 2.0 版中是新增的公共方法：\n\n通知运行库在安排垃圾回收时应考虑分配大量的非托管内存\npublic static void AddMemoryPressure (\nlong bytesAllocated)//bytesAllocated已分配的非托管内存的增量。", age = 30};
        t.stu = s1;
        s1 = null;
        // t.stu = null;
        Debug.Log("Memory："+GC.GetTotalMemory(true));
        // Debug.Log(t.stu == null);
        // Debug.Log($"{t.stu?.name} {t.stu?.age}");
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Debug.Log("点击");
            Debug.Log($"Memory：{GC.GetTotalMemory(true)/ 1024f / 1024f:F2} MB");
        }
        
        // 按下空格键时打印内存使用情况
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // 总内存使用（包括托管和非托管内存）
            long totalReservedMemory = UnityEngine.Profiling.Profiler.GetTotalReservedMemoryLong();
            long totalAllocatedMemory = UnityEngine.Profiling.Profiler.GetTotalAllocatedMemoryLong();
            long totalUnusedReservedMemory = UnityEngine.Profiling.Profiler.GetTotalUnusedReservedMemoryLong();
            
            // 纹理、网格等资源的内存使用
            long monoMemory = UnityEngine.Profiling.Profiler.GetMonoUsedSizeLong();
            long meshMemory = UnityEngine.Profiling.Profiler.GetAllocatedMemoryForGraphicsDriver();
            
            // 打印内存使用情况
            Debug.Log($"Total Reserved Memory: {totalReservedMemory / 1024f / 1024f:F2} MB");//返回Unity保留的总内存量（包括未使用的内存）。
            Debug.Log($"Total Allocated Memory: {totalAllocatedMemory / 1024f / 1024f:F2} MB");//返回Unity实际分配的内存量。
            Debug.Log($"Total Unused Reserved Memory: {totalUnusedReservedMemory / 1024f / 1024f:F2} MB");//返回保留但未使用的内存量。
            Debug.Log($"托管堆 Memory: {monoMemory / 1024f / 1024f:F2} MB");//返回Mono运行时使用的内存量。反映了 C# 脚本中的对象、数组等托管资源的内存占用。
            Debug.Log($"Mesh Memory: {meshMemory / 1024f / 1024f:F2} MB");//返回图形驱动程序分配的内存量。
        }
    }
}
